# coding:utf-8

from flask import flash, render_template, url_for, redirect, request
from flask_login import login_required
import xlrd

from app.models import get_timestamp
from app.op.constant import MAX_ROW_COUNT, AreaType
from app.op.models import Area
from . import axb_bp
from .models import NumberPoolForLT, VirtualNumber
from .constant import VirtualNumberValid
from .number_forms import ImportNumberForm, SearchNumberForm, AreaNumberForm
from .number_schemas import ImportNumberLTSchema


@axb_bp.route('/number/import/lt', methods=['GET', 'POST'])
@login_required
def import_number_lt():
    """
    created by chenhj at 2017/10/10
    导入联通号码
    """
    form = ImportNumberForm()
    error_msg = list()
    if form.validate_on_submit():
        book = xlrd.open_workbook(file_contents=form.files.data.stream.read())
        sheet = book.sheet_by_index(0)
        mobile_map = dict()
        data_list = list()
        if sheet.nrows <= MAX_ROW_COUNT:
            for row in range(0, sheet.nrows):
                row_num = row + 1
                schema = ImportNumberLTSchema(sheet, row)

                mobile = schema.mobile
                # 若文件中有重复手机号, 则提示
                if mobile in mobile_map:
                    error_msg.append(
                        (row_num, '该电话工程商在文件已存在, 请检查文件')
                    )
                    continue

                mobile_map[mobile] = row_num
                if schema.error_msg:
                    error_msg.extend(schema.error_msg)
                    continue

                data_list.append(schema)

            phones = NumberPoolForLT.query.filter(NumberPoolForLT.tel.in_(
                filter(lambda x: x, mobile_map.keys()))
            )
            for each in phones:
                error_msg.append(
                    (mobile_map[each.tel], '该电话已存在系统中, 不可重复添加')
                )
            if error_msg:
                error_msg = sorted(error_msg, key=lambda x: x[0])
            else:
                for each in data_list:
                    city = Area.query.filter(
                        Area.type == AreaType.CITY.value,
                        Area.name.like('{}%'.format(each.city))
                    ).first()
                    NumberPoolForLT.create(
                        area_id=city.id,
                        tel=each.mobile
                    )
                flash('上传成功')
                return redirect(url_for('axb_bp.number_list_lt'))
        else:
            flash(
                '上传数据不可超过{}行，若数据过多请分多次上传！'.format(MAX_ROW_COUNT)
            )
    return render_template(
        'number/import_lt.html', form=form, error_msg=error_msg
    )


@axb_bp.route('/number_list/lt', methods=['GET', 'POST'])
@login_required
def number_list_lt():
    """
    created by chenhj at 2017/10/10
    联通号码池列表
    """
    form = SearchNumberForm(formdata=request.form or request.args)
    area_toogle_form = AreaNumberForm()

    query = NumberPoolForLT.query
    url_kwargs = {}
    if form.validate():
        query_kwargs, url_kwargs = form.generate_kwargs()
        query = NumberPoolForLT.generate_list_query_condition(
            args=url_kwargs,
            query=query
        )

    page = request.args.get('page', 1, type=int)
    pagination = query.order_by(NumberPoolForLT.id.asc()).paginate(
        # page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        page, per_page=1000,
        error_out=False)
    items = pagination.items

    return render_template(
        'number/numbers_lt.html',
        form=form,
        area_toogle_form=area_toogle_form,
        items=items,
        pagination=pagination,
        url_kwargs=url_kwargs,
    )


@axb_bp.route('/number/lt/toggle/<tel>')
def number_lt_toggle(tel):
    """
    created by chenhj at 2017/12/6
    启用/禁用虚拟号
    """
    data = NumberPoolForLT.get_by_args(tel=tel)

    if data.enterprise_id:
        flash('该号码当前被金牌/银牌使用，无法进行启用/禁用操作，请联系管理员')
        return redirect(url_for('axb_bp.number_list_lt'))

    # 启用号码
    if data.deleted_at:
        data.deleted_at = 0
        flash('启用成功')
        return redirect(url_for('axb_bp.number_list_lt'))

    # 禁用号码, 需要为其他已生效的虚拟号关系生成一个新的关系
    virtual_number_list = VirtualNumber.get_list_by_args(
        valid=VirtualNumberValid.VALID.value,
        tel_x=tel,
        for_sms=False
    )

    substitute_flag = True
    error_tel_x = []
    for each in virtual_number_list:
        substitute_number = NumberPoolForLT.get_substitute_number(
            tel_a=each.tel_a,
            tel_b=each.tel_b,
            area_id=data.area_id,
        )
        if substitute_number:
            each.tel_x = substitute_number.tel
            data.use_count -= 1
            substitute_number.use_count += 1
        else:
            substitute_flag = False
            if each.tel_x not in error_tel_x:
                error_tel_x.append(each.tel_x)

    if substitute_flag:
        data.deleted_at = get_timestamp()
        flash('禁用成功')
    else:
        flash('以下虚拟号所属关系替换失败:{error_tel_x}'.format(
            error_tel_x=','.join(error_tel_x)
        ))

    return redirect(url_for('axb_bp.number_list_lt'))


@axb_bp.route('/number/lt/area/valid', methods=['POST'])
def number_lt_area_valid():
    """
    add by zhouhl 2018-04-02
    按照地区启用虚拟号
    """
    area_toogle_form = AreaNumberForm(formdata=request.form)
    numbers = NumberPoolForLT.get_list_by_args(
        area_id=area_toogle_form.area_id.data
    )
    for number in numbers:
        number.deleted_at = 0

    flash('启用成功')
    return redirect(url_for('axb_bp.number_list_lt'))


@axb_bp.route('/number/lt/area/invalid', methods=['POST'])
def number_lt_area_invalid():
    """
    add by zhouhl 2018-04-02
    按照地区禁用虚拟号
    """
    area_toogle_form = AreaNumberForm(formdata=request.form)
    numbers = NumberPoolForLT.get_list_by_args(
        area_id=area_toogle_form.area_id.data,
        deleted_at=0,
        enterprise_id=0,
    )
    tel_x_list = [i.tel for i in numbers]

    # 使用这些号码的 VirtualNumber 需要更新 tel_x
    virtual_number_list = VirtualNumber.query.filter(
        VirtualNumber.valid==VirtualNumberValid.VALID.value,
        VirtualNumber.for_sms==False
    )
    if tel_x_list:
        virtual_number_list = virtual_number_list.filter(
            VirtualNumber.tel_x.in_(tel_x_list),
        )
    substitute_flag = True
    error_tel_x = []
    for each in virtual_number_list:
        substitute_number = NumberPoolForLT.get_substitute_number(
            tel_a=each.tel_a,
            tel_b=each.tel_b,
            invalid_area=area_toogle_form.area_id.data,
        )
        if substitute_number:
            each.tel_x = substitute_number.tel
            substitute_number.use_count += 1
        else:
            substitute_flag = False
            if each.tel_x not in error_tel_x:
                error_tel_x.append(each.tel_x)

    for number in numbers:
        if number.tel not in error_tel_x:
            number.deleted_at = get_timestamp()
            # 需要计算短信使用的次数
            number.use_count = VirtualNumber.query.filter(
                VirtualNumber.valid==VirtualNumberValid.VALID.value,
                VirtualNumber.for_sms==True,
                VirtualNumber.tel_x==number.tel
            ).count()
            # number.use_count = 0

    if substitute_flag:
        flash('禁用成功(注意，金牌/银牌使用的号码不可禁用)')
    else:
        error_msg = ''
        for i in range(0, len(error_tel_x) // 6 + 1):
            error_msg += ','.join(error_tel_x[i * 6 : (i + 1) * 6]) + '\r\n'

        flash('以下虚拟号所属关系替换失败:\r\n{error_msg}'.format(
            error_msg=error_msg
        ))
    return redirect(url_for('axb_bp.number_list_lt'))


